package com.example.bank.domain;

import com.example.bank.pojo.User;
import com.example.bank.service.user.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * @author ：Leeziqiang
 * @description：ShiroRealm
 * @date ：2021/11/22 14:51
 */
@SuppressWarnings("serial")
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserService service;


    // 限定这个Realm只处理UsernamePasswordToken
    @Override
    public boolean supports(AuthenticationToken token) {
        return super.supports(token);
    }

    // 查询数据库，将获取到的用户安全数据封装返回
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 从AuthenticationToken中获取当前用户
        String id = (String) token.getPrincipal();
        // 查询数据库获取用户信息，此处使用Map来模拟数据库
        //User user = userMap.get(id);
        User user = service.getById(id);

        // 用户不存在
        if (user == null) {
            throw new UnknownAccountException("用户不存在");
        }
        // 使用用户名(用户id)作为盐值
        ByteSource salt = ByteSource.Util.bytes(id);

        // 将获取到的用户数据封装成AuthenticationInfo对象返回，此处封装为SimpleAuthenticationInfo 对象
        // 参数一：认证的实体信息，可以是从数据库中获取到的用户实体类对象或者用户名
        // 参数二：查询获取到的登录密码
        // 参数三：盐值
        // 参数四：当前Realm对象的名称，直接调用父类的getName()方法即可
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), salt, getName());
        return info;
    }

    // 查询数据库，将获取到的用户的角色及权限信息返回
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取当前用户
        User currentUser = (User) SecurityUtils.getSubject().getPrincipal();
        // 查询数据库，获取用户的角色信息
        Set<String> roles = new HashSet<String>();
        String role = service.findRoleByUserId(currentUser.getUserId());
        roles.add(role);
        // 查询数据库获取用户的权限信息
        Set<String> perms = new HashSet<String>();
        String perm = service.findRoleByUserId(currentUser.getUserId());
        perms.add(perm);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);
        info.setStringPermissions(perms);
        return info;
    }


}
